package com.wframe.project.jnd.util;

import com.frame.database.JdataBean;
import com.wframe.project.jnd.entity.BuySendPromotion;
import com.wframe.project.jnd.entity.FlashSalePromotion;
import com.wframe.project.jnd.entity.Promotion;
import com.wframe.project.jnd.rest.util.ClientException;
import com.wframe.project.jnd.rest.util.CodeEnum;
import com.wframe.project.jnd.services.CouponService;
import com.wframe.project.jnd.services.OrderService;
import com.wframe.project.jnd.services.ProductService;
import com.wframe.project.jnd.services.PromotionService;
import com.wframe.project.jnd.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by lwb on 2017/6/9.
 */
@Component
public class ComplexPromotionsBuilder implements PromotionBuilder {
    @Autowired
    protected PromotionService promotionService;

    @Autowired
    protected ProductService productService;

    @Autowired
    protected OrderService orderService;

    @Autowired
    protected CouponService couponService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("REDIS_PROMOTION")
    private String namespace;

    @Override
    public Promotion build(String promotionId) throws Exception {
        return null;
    }

    public CartBean getData(String userid, String promotionId, List<CartItem> prices, int platform, Map<String, Integer> tempProductStock) throws Exception {
        CartBean bean = new CartBean();
        CartItem item = prices.get(0);
        List<CartProductVO> products = new ArrayList<>();

        //处理有其他促销的情况
        CartProductVO productVO = otherPromotionProcess(userid, item, promotionId, platform, tempProductStock);
        //处理买送促销的赠品
        products = addProduct(products, promotionId, productVO);
        bean.setProducts(products);
        if (item.isCheck()) {
            bean.setTotalPrice(productVO.getTotalPrice());
        } else {
            bean.setTotalPrice(BigDecimal.ZERO);
        }
        bean.setPromotionId(promotionId);
        return bean;
    }

    @Override
    public CartBean getCartProducts(String userid, String promotionId, List<CartItem> prices, int platform, Map<String, Integer> tempProductStock) throws Exception {
        CartBean bean = new CartBean();
        Map<String, CartItem> map = new HashMap<>();
        for (CartItem item : prices) {
            map.put(String.valueOf(item.getProductid()), item);
        }

        //处理有其他促销的情况
        Map<String, Object> process = otherPromotionProcess(userid, map, platform, tempProductStock);
        bean.setProducts((List<CartProductVO>) process.get("products"));
        bean.setTotalPrice((BigDecimal) process.get("totalPrice"));
        bean.setPromotionId(promotionId);
        return bean;
    }

    @Override
    public CartBean process(Map.Entry<String, List<JdataBean>> entry, Map<String, Integer> tempProductStock) throws Exception {
        CartBean result = new CartBean();

        List<CartProductVO> products = new ArrayList<>();
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (JdataBean item : entry.getValue()) {
            CartProductVO productVO = otherPromotionProcess(item, tempProductStock);
            products.addAll(addProduct(productVO));
            totalPrice = totalPrice.add(productVO.getTotalPrice());
        }

        result.setProducts(products);
        result.setTotalPrice(totalPrice);
        return result;
    }

    protected CartProductVO otherPromotionProcess(JdataBean item, Map<String, Integer> tempProductStock) {
        CartProductVO productVO = new CartProductVO();
        List<String> ids = new ArrayList<>();
        Map promotionAmount = new HashMap();

        String productid = item.getString("productid");
        productVO.setId(Integer.parseInt(productid));
        productVO.setName(item.getString("name"));
        //商品可用库存
        int amount = item.getInt("amount");
        //商品价格
        BigDecimal price = item.getBigDecimal("price");
        //商品购买数量
        int buyNum = item.getInt("count");

        if (item.getInteger("fs_type") != null) {
            //单品促销控销通过
            String promotionId = item.getString("fs_promotionid");
            //商品参与了单品促销
            productVO.setFlashSale(true);
            int inventory = item.getInt("fs_amount");
            amount = amount > inventory ? inventory : amount;
            price = item.getBigDecimal("fs_price");
            productVO.setFlashSaleAvailableInventory(item.getInteger("fs_time"));

            ids.add(promotionId);
            promotionAmount.put(promotionId, buyNum);
        }

        if (item.getInteger("bs_type") != null) {
            //买送促销控销通过
            String promotionId = item.getString("bs_promotionid");
            productVO.setGiftPromotionId(promotionId);
            Integer times = item.getInteger("bs_time");
            if (times == null || times > 0) {
                //买送促销无限购次数或者还有次数
                productVO.setBuySend(true);
                //买送促销的起送数量
                int standardNum = item.getInt("buy_number");
                productVO.setStandardNum(standardNum);
                //买送促销的赠送数量
                int sendNumber = item.getInt("send_number");
                productVO.setSendNum(sendNumber);

                //买送次数
                int giftNum = buyNum / standardNum;
                if (times != null) {
                    //最大买送次数
                    giftNum = giftNum > times ? times : giftNum;
                }
                //预计赠送数量
                giftNum = giftNum * sendNumber;
                //减去购买的商品数量后的库存
                int predictNum = tempProductStock.get(productid);
                productVO.setShortage(giftNum > predictNum);
                //实际赠送数量
                giftNum = giftNum > predictNum ? predictNum : giftNum;
                productVO.setGiftNum(giftNum);

                tempProductStock.put(productid, predictNum - giftNum);

                //实际赠送的次数向上取整
                giftNum = (giftNum + sendNumber - 1) / sendNumber;
                if (giftNum > 0) {
                    productVO.setAvailable(true);
                    promotionAmount.put(promotionId, giftNum);
                }

                ids.add(promotionId);
            }
        }
        //商品所有促销id
        productVO.setPromotionIds(ids);
        //商品促销库存
        productVO.setPromotionAmount(promotionAmount);
        //商品库存
        productVO.setAmount(amount);
        //商品价格
        productVO.setPrice(price);
        //购买数量
        productVO.setBuyNum(buyNum);
        //订单项总价
        productVO.setTotalPrice(productVO.getPrice().multiply(BigDecimal.valueOf(buyNum)));
        return productVO;
    }

    protected Map<String, Object> otherPromotionProcess(String userid, Map<String, CartItem> items, int platform, Map<String, Integer> tempProductStock) {
        BigDecimal totalPrice = BigDecimal.ZERO;
        Map<String, CartProductVO> temp = new HashMap<>();
        Map<String, List<Coupon>> couponMap = new HashMap<>();
        Map<String, Object> result = new HashMap<>();

        Set<String> ids = items.keySet();
        List<Product> products = productService.findPowerProducts(userid, ids);
        for (Product product : products) {
            CartProductVO productVO = new CartProductVO();
            String productid = String.valueOf(product.getId());

            Product base = productService.findOne(productid);
            productVO.setPhoto(base.getPhoto());
            productVO.setName(base.getName());
            productVO.setB_chanjia(base.getManufacturers());
            productVO.setB_guige(base.getSpecification());
            productVO.setUnit(base.getUnit());

            CartItem item = items.get(productid);
            productVO.setId(item.getProductid());
            productVO.setCartId(item.getId());
            productVO.setCheck(item.isCheck());
            //购买数量
            int count = item.getCount();
            productVO.setBuyNum(count);

            productVO.setPrice(product.getPrice());
            int amount = product.getAmount();
            //商品库存
            productVO.setAmount(amount > 0 ? amount : 0);
            //商品常购
            productVO.setOften(product.isFavorite());

            temp.put(productid, productVO);
        }

        List<BuySendPromotion> buySendes = promotionService.findBuySend(userid, ids);
        for (BuySendPromotion buySend : buySendes) {
            Integer promotionId = buySend.getId();
            String productid = String.valueOf(buySend.getProductid());
            CartProductVO product = temp.get(productid);
            int count = product.getBuyNum();

            product.setBuySend(true);

            int standardNum = buySend.getBuyNumber();
            product.setStandardNum(standardNum);
            int sendNumber = buySend.getSendNumber();
            product.setSendNum(sendNumber);

            //买送次数
            int giftNum = count / standardNum;
            Integer time = buySend.getTime();
            if (Objects.nonNull(time)) {
                //最大买送次数
                giftNum = giftNum > time ? time : giftNum;
            }
            //预计赠送数量
            giftNum = giftNum * sendNumber;
            //减去购买的商品数量后的库存
            int predictNum = tempProductStock.get(productid);
            product.setShortage(giftNum > predictNum);
            //实际赠送数量
            giftNum = giftNum > predictNum ? predictNum : giftNum;
            product.setGiftNum(giftNum);
            tempProductStock.put(productid, predictNum - giftNum);
            tempProductStock.put(productid + "_" + promotionId, giftNum);

            //实际赠送的次数向上取整
            giftNum = (giftNum + sendNumber - 1) / sendNumber;
            if (giftNum > 0) {
                product.setAvailable(true);
            }

            temp.put(productid, product);
        }

        List<FlashSalePromotion> flashSales = promotionService.findFlashSale(userid, ids, platform);
        for (FlashSalePromotion flashSale : flashSales) {
            String productid = String.valueOf(flashSale.getProductid());
            CartProductVO product = temp.get(productid);

            product.setFlashSale(true);
            product.setFlashSaleAvailableInventory(flashSale.getTime());
            product.setPrice(flashSale.getPrice());
            //商品库存
            product.setAmount(flashSale.getAmount());

            temp.put(productid, product);
        }

        Collection<CartProductVO> productVOS = temp.values();
        Iterator<CartProductVO> it = productVOS.iterator();
        while (it.hasNext()) {
            CartProductVO product = it.next();
            BigDecimal price = product.getPrice();
            int count = product.getBuyNum();
            //订单项总价
            BigDecimal unitTotalPrice = BigDecimal.ZERO;
            if (product.isCheck()) {
                unitTotalPrice = price.multiply(BigDecimal.valueOf(count));
            }
            product.setTotalPrice(unitTotalPrice);

            totalPrice = totalPrice.add(unitTotalPrice);
        }

        result.put("products", new ArrayList<>(productVOS));
        result.put("totalPrice", totalPrice);
        return result;
    }

    @Override
    public boolean checkInventoryChange(Map<String, Integer> sessionProductStock, CartBean item) {
        List<CartProductVO> products = item.getProducts();
        for (CartProductVO product : products) {
            CartProductVO.GiftType giftType = product.getGiftType();
            if (giftType != null) {
                //赠品数量校验
                if (product.getBuyNum() != sessionProductStock.get(product.getId() + "_" + product.getGiftPromotionId())) {
                    return true;
                }
            }
        }
        return false;
    }

    protected CartProductVO otherPromotionProcess(String userid, CartItem item, String key, int platform, Map<String, Integer> tempProductStock) throws Exception {
        String productid = String.valueOf(item.getProductid());
        JdataBean info = productService.getProductInfo(productid);

        CartProductVO productVO = TransformUtils.trans(info, CartProductVO.class);
        productVO.setPrice(BigDecimal.valueOf(Double.parseDouble(String.valueOf(productService.findAppositePrice(userid, productid)))));
        productVO.setCartId(item.getId());
        productVO.setCheck(item.isCheck());

        List<String> ids = new ArrayList<>();
        Map promotionAmount = new HashMap();
        //商品可用库存
        int amount = productVO.getAmount();
        //商品购买数量
        int buyNum = item.getCount();
        if (amount > 0) {
            JdataBean flashSale = promotionService.findFlashSaleByProductId(productid, userid, platform);
            if (Objects.nonNull(flashSale)) {
                //单品促销控销通过
                String promotionId = flashSale.getString("id");
                Integer number = promotionService.getResidualNumber(userid, promotionId);
                if (Objects.isNull(number) || number > 0) {
                    //商品参与了单品促销
                    productVO.setFlashSale(true);
                    productVO.setPrice(flashSale.getBigDecimal("price"));
                    //可用库存
                    int inventory = flashSale.getInt("amount");
                    amount = inventory > amount ? amount : inventory;

                    productVO.setFlashSaleAvailableInventory(number);

                    ids.add(promotionId);
                    promotionAmount.put(promotionId, buyNum);
                }
            }

            JdataBean buySend = promotionService.findBuySendByProductId(productid, userid);
            if (Objects.nonNull(buySend)) {
                //买送促销控销通过
                String promotionId = buySend.getString("id");
                Integer times = promotionService.getResidualNumber(userid, promotionId);
                if (Objects.isNull(times) || times > 0) {
                    //买送促销无限购次数或者还有次数
                    productVO.setBuySend(true);
                    //买送促销的起送数量
                    int standardNum = buySend.getInt("buy_number");
                    productVO.setStandardNum(standardNum);
                    //买送促销的赠送数量
                    int sendNumber = buySend.getInt("send_number");
                    productVO.setSendNum(sendNumber);

                    //买送次数
                    int giftNum = buyNum / standardNum;
                    if (Objects.nonNull(times)) {
                        //最大买送次数
                        giftNum = giftNum > times ? times : giftNum;
                    }
                    //预计赠送数量
                    giftNum = giftNum * sendNumber;
                    //减去购买的商品数量后的库存
                    int predictNum = tempProductStock.get(productid);
                    productVO.setShortage(giftNum > predictNum);
                    //实际赠送数量
                    giftNum = giftNum > predictNum ? predictNum : giftNum;
                    productVO.setGiftNum(giftNum);

                    tempProductStock.put(productid, predictNum - giftNum);
                    tempProductStock.put(productid + "_" + key, giftNum);

                    //实际赠送的次数向上取整
                    giftNum = (giftNum + sendNumber - 1) / sendNumber;
                    if (giftNum > 0) {
                        productVO.setAvailable(true);
                        promotionAmount.put(promotionId, giftNum);
                    }

                    ids.add(promotionId);
                }
            }
        } else {
            amount = 0;
            buyNum = 0;
        }
        //商品所有促销id
        productVO.setPromotionIds(ids);
        //商品促销库存
        productVO.setPromotionAmount(promotionAmount);
        //商品库存
        productVO.setAmount(amount);
        //购买数量
        productVO.setBuyNum(buyNum);
        //订单项总价
        productVO.setTotalPrice(productVO.getPrice().multiply(BigDecimal.valueOf(buyNum)));
        //商品常购
        productVO.setOften(productService.checkfavorite(userid, productid));
        return productVO;
    }

    protected List<CartProductVO> addProduct(List<CartProductVO> products, String promotionId, CartProductVO productVO) throws CloneNotSupportedException {
        CartProductVO buySendProduct = null;

        int buyNum = productVO.getBuyNum();
        Integer standardNum = productVO.getStandardNum();
        if (standardNum != null && standardNum > 0 && buyNum >= standardNum) {
            //买送促销的赠品
            buySendProduct = (CartProductVO) productVO.clone();
            buySendProduct.setGiftType(CartProductVO.GiftType.BUY_SEND);
            buySendProduct.setPrice(BigDecimal.ZERO);
            buySendProduct.setTotalPrice(BigDecimal.ZERO);
            buySendProduct.setBuyNum(productVO.getGiftNum());
        }

        products.add(productVO);
        if (buySendProduct != null && buySendProduct.getBuyNum() > 0) {
            products.add(buySendProduct);
        }
        return products;
    }

    protected List<CartProductVO> addProduct(CartProductVO productVO) throws CloneNotSupportedException {
        List<CartProductVO> products = new ArrayList<>();
        products.add(productVO);

        if (productVO.isAvailable()) {
            //买送促销的赠品
            CartProductVO buySendProduct = (CartProductVO) productVO.clone();
            buySendProduct.setGiftType(CartProductVO.GiftType.BUY_SEND);
            buySendProduct.setPrice(BigDecimal.ZERO);
            buySendProduct.setTotalPrice(BigDecimal.ZERO);
            buySendProduct.setBuyNum(productVO.getGiftNum());
            products.add(buySendProduct);
        }

        return products;
    }

    protected int getInventory(JdataBean flashSale) {
        //可用活动库存
        Object inventory = redisTemplate.opsForHash().get(namespace, flashSale.getString("id"));
        if (inventory == null) {
            //缓存未命中
            inventory = flashSale.getInt("amount");
        }
        return Integer.parseInt(String.valueOf(inventory));
    }

}
